////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

#ifndef __WN_CORE_ASSERT_INL__
#define __WN_CORE_ASSERT_INL__

#ifndef __WN_CORE_ASSERT_H__
    #error "WNAssert.inl should never be included directly. Please include WNAssert.h instead"
#endif

#include "WNCore/inc/WNPlatform.h"
#include "WNCore/inc/WNMacros.h"
#include "WNCore/inc/WNAssert.h"

#ifdef _WN_WINDOWS
    #include <windows.h>
    #include <tchar.h>
#else
    #include <stdio.h>
#endif

#include <assert.h>

WN_INLINE WN_VOID __WNAssert(WN_INT32 _argument, const WN_CHAR* _file, WN_UINT32 _line, const WN_CHAR* _message) {
    if (_argument == 0) {
        #ifdef _WN_WINDOWS
            TCHAR display[1024];
            TCHAR program[MAX_PATH];

            ZeroMemory(display, 1024);
            ZeroMemory(program, MAX_PATH);

            #ifdef _WN_UNICODE
                TCHAR file[MAX_PATH];
                TCHAR message[512];

                ZeroMemory(file, MAX_PATH);
                ZeroMemory(message, 512);
            #endif

            GetModuleFileName(NULL, program, MAX_PATH);

            #ifdef _WN_UNICODE
                MultiByteToWideChar(CP_ACP, 0, _file, -1, file, MAX_PATH + 1);
                MultiByteToWideChar(CP_ACP, 0, _message, -1,  message, 512);

                swprintf_s(display, L"Assertion failed!\n\nProgram: %s\nFile: %s\nLine: %d\n\nExpression: %s", program, file, _line, message);
            #else
                sprintf_s(display, "Assertion failed!\n\nProgram: %s\nFile: %s\nLine: %d\n\nExpression: %s", program, _file, _line, _message);
            #endif

            MessageBox(NULL, display, _T("Assertion Failed!"), MB_OK | MB_ICONHAND | MB_SETFOREGROUND | MB_TASKMODAL);
        #else
            WN_PRINTF("Assertion failed!\n\nFile: %s\nLine: %d\n\nExpression: %s", _file, _line, _message);
        #endif

        WN_DEBUG_BREAK();

        assert(WN_FALSE);
    }
}

#endif // __WN_CORE_ASSERT_INL__